pub(crate) mod crawl_etf_todo;
pub(crate) mod crawl_kzz_todo;
pub(crate) mod crawl_opf_todo;
pub(crate) mod crawl_stock_todo;
pub(crate) mod crawl_index_todo;
pub(crate) mod sync_securities_todo;
pub(crate) mod sync_klines_todo;
pub(crate) mod evenly_hosts;
pub(crate) mod worker_his;
pub(crate) mod worker_query;
pub(crate) mod worker_sync;
pub(crate) mod worker_sse;
pub(crate) mod sse_tick3_todo;
pub(crate) mod sse_minute1klines_todo;

use chrono::Local;
use fudata::db;
use fudata::model::kline::Klt;
use fudata::model::todo;
use fudata::model::todo::Todo;
use fudata::model::todo::TodoFailure;
use log::error;

pub const MAX_IDX_SECURITY: u16 = 10000;
pub const MAX_STK_SECURITY: u16 = 10000;
pub const MAX_KZZ_SECURITY: u16 = 10000;
pub const MAX_ALL_SECURITY: u16 = 30000;

pub const RECEIVE_TIMEOUT_MS: u64 = 3 * 1000; //mill seconds

pub const MAX_WORKERS: u8 = 4;
pub const MAX_QUEUE_SIZE: u8 = 100;
/// 2500 days, 10 years for A stocks is engough, the data before 10 yeasrs is not useful
pub const MAX_KLINE_DAYS: i64 = 2500;

pub const EASYMONEY_KLTS: [Klt; 7] = [
    Klt::M005,
    Klt::M015,
    Klt::M030,
    Klt::M060,
    Klt::DAY,
    Klt::WEEK,
    Klt::MONTH,
];

pub async fn update_todo_with_result<T>(
    worker_no: u8,
    rs: std::result::Result<T, anyhow::Error>,
    todo: &Todo
) {
    match rs {
        Ok(_) => {
            let todo_update = Todo {
                status: Some(todo::TodoStatus::Done),
                ..Default::default()
            };
            let _ = db::todo::upsert(&todo.id.clone().unwrap().id.to_raw(), &todo_update).await;
        }
        Err(e) => {
            error!("Worker[{worker_no}] update_todo_with_result {:?} error: {}", &todo.id, e);
            let mut failures = todo.failures.clone().unwrap_or_default();
            failures.push(TodoFailure {
                message: e.to_string(),
                failure_at: Local::now(),
            });

            let todo_update = Todo {
                status: Some(todo::TodoStatus::Failed),
                failures: Some(failures),
                ..Default::default()
            };
            let _ = db::todo::upsert(&todo.id.clone().unwrap().id.to_raw(), &todo_update).await;
        }
    }
}
